"""
决策树的几种算法
"""
import time
from sklearn.datasets import make_blobs
from sklearn.ensemble import RandomForestClassifier, AdaBoostClassifier
from sklearn.tree import DecisionTreeClassifier
from sklearn.model_selection import cross_val_score
from sklearn.metrics import accuracy_score


class DataScore:
    """
    数据生成，及评估模型得分
    """
    def __init__(self):
        dataset_sample_size = 10000
        dataset_features_of_each_sample = 10
        dataset_center_num = 100
        self.random_state = 0
        self.num_jobs = 2
        self.x, self.y = make_blobs(n_samples=dataset_sample_size,
                                    n_features=dataset_features_of_each_sample,
                                    centers=dataset_center_num,
                                    random_state=self.random_state)
        self.cross_num_folds = 5

    def scores(self, clf):
        """

        :param clf:
        :return:
        """
        begin = time.time()
        scores = cross_val_score(clf, self.x, self.y, cv=self.cross_num_folds)
        end = time.time()

        clf.fit(self.x, self.y)
        y_pred = clf.predict(self.x)
        accuracy = accuracy_score(self.y, y_pred)
        return accuracy * 100, scores.mean(), end - begin


def signal_tree():
    """
    决策树
    :return:
    """
    max_depth = None
    min_samples_split = 2

    data_scores = DataScore()
    clf = DecisionTreeClassifier(min_samples_split=min_samples_split,
                                 max_depth=max_depth,
                                 random_state=data_scores.random_state)
    accuracy, score, cost_times = data_scores.scores(clf=clf)
    print('descition tree: accuarcy: {}, scores: {}, cost: {}'.
          format(accuracy, score, cost_times))


def random_forest():
    """
    随机森林
    :return:
    """
    num_trees = 10
    max_depth = None
    min_samples_split = 2

    data_scores = DataScore()
    clf = RandomForestClassifier(n_estimators=num_trees,
                                 min_samples_split=min_samples_split,
                                 max_depth=max_depth,
                                 n_jobs=data_scores.num_jobs,
                                 random_state=data_scores.random_state)
    accuracy, score, cost_times = data_scores.scores(clf=clf)
    print('random forest: accuarcy: {}, scores: {}, cost: {}'.
          format(accuracy, score, cost_times))


def adaboost():
    """
    adaboost
    :return:
    """
    week_classiifier = DecisionTreeClassifier(max_depth=3)
    max_iter = 100
    learning_rate = 0.85
    algorithm = 'SAMME.R'

    data_scores = DataScore()
    clf = AdaBoostClassifier(base_estimator=week_classiifier,
                             n_estimators=max_iter, algorithm=algorithm,
                             learning_rate=learning_rate,
                             random_state=data_scores.random_state)
    accuracy, score, cost_times = data_scores.scores(clf=clf)
    print('adaboost: accuarcy: {}, scores: {}, cost: {}'.
          format(accuracy, score, cost_times))


def run():
    # decision tree
    signal_tree()

    # random forest
    random_forest()

    # adaboost
    adaboost()


if __name__ == '__main__':
    run()
